﻿using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using SIG.Infrastructure.Helper;
using SIGBugs.Server.DataAccess;
using SIGBugs.Server.ViewModels;
using SIGBugs.Shared.InputModels;
using SIGBugs.Shared.Models;

namespace SIGBugs.Server.Controllers
{
    [Produces("application/json")]
    [Route("api/[controller]")]
    public class AccountController : Controller
    {
        private readonly BugsContext _context;
        private readonly TokenOptions _tokenOptions;
        public AccountController(BugsContext context, IOptions<TokenOptions> tokens)
        {
            _context = context;
            _tokenOptions = tokens.Value;
        }
       

        [HttpPost]
        [AllowAnonymous]
        public async Task<IActionResult> Token([FromBody] LoginIM model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest();
            }

            var user = await _context.Users.FirstOrDefaultAsync(d => d.Username == model.Username);
            var salt = Convert.FromBase64String(user.SecurityStamp);
            var pwdHash = Hash.HashPasswordWithSalt(model.Password, salt);
               
            if (user.PasswordHash != pwdHash)
            {               
                return BadRequest("用户名或密码不正确。");
            }

            var token = await GetJwtSecurityTokenAsync(user);
            return Ok(new JwtSecurityTokenHandler().WriteToken(token));
        }
        private async Task<JwtSecurityToken> GetJwtSecurityTokenAsync(User user)
        {
            // var userClaims = await _userManager.GetClaimsAsync(user);
            // create claims
            List<Claim> claims = new List<Claim>
            {
                new Claim(ClaimTypes.Sid, user.Id.ToString()),
                new Claim("RealName", user.RealName??"无"),
                new Claim(ClaimTypes.Name, user.Username),
                new Claim(ClaimTypes.Email, user.Email)
            };
           
            var userRoles = await _context.Roles.Where(d => d.UserRoles.Any(ur => ur.UserId == user.Id)).ToArrayAsync();
                //_roleServices.GetRolesByUserId(user.Id).ToArray();
            //add a list of roles

            if (userRoles.Any())
            {
                var roles = string.Join(",", userRoles.Select(d => d.RoleName));
                claims.Add(new Claim(ClaimTypes.Role, roles));
            }

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_tokenOptions.Key));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            return new JwtSecurityToken(
                issuer: _tokenOptions.Issuer,
                audience: _tokenOptions.Issuer,
                claims: claims,
                expires: DateTime.UtcNow.AddMinutes(30),
                signingCredentials: creds
            );
        }


       
    }
}